<!--
 * @Description: 背景音乐
 * @Date: 2024-11-28 17:33:13
 * @FilePath: \demod:\12electron\electron-demo\src\renderer\src\components\bgMusic.vue
-->
<template>
  <div class="bg-music">
    <div class="music-player">
      <div class="list" @click="onListClick">
        <img alt="音乐列表" title="音乐列表" src="@renderer/assets/img/music.svg" />
        列表
      </div>
      <div class="bar">
        <div class="title-box">
          <div class="music-name">{{ state.currentSong.name || '--' }}</div>
          <div class="music-time">{{ state.currentTime?.toFixed(1) || '--' }} / {{ state.totalTime?.toFixed(1) || '--' }}</div>
        </div>
        <div class="progress-box">
          <ProgressBar
            :maxValue="state.totalTime"
            v-model:currentValue="state.currentTime"
            :showCircle="true"
            @change="onMusicProgressChange" />
        </div>
      </div>
    </div>

    <div class="music-operate">
      <div class="previous" @click="prev">
        <img alt="上一首" title="上一首" src="@renderer/assets/img/pre.svg" />
      </div>
      <div class="play" @click="onClickPlay">
        <img v-if="state.isPlay" alt="暂停" title="暂停" src="@renderer/assets/img/pause.svg" />
        <img v-else alt="播放" title="播放" src="@renderer/assets/img/play.svg" />
      </div>
      <div class="next" @click="next">
        <img alt="下一首" title="下一首" src="@renderer/assets/img/next.svg" />
      </div>
    </div>

    <div class="voice-controller">
      <img alt="声音" title="声音" src="@renderer/assets/img/voice.svg" style="margin-right: 12px" />
      <ProgressBar
        :maxValue="100"
        v-model:currentValue="currentVolume"
        :showCircle="true"
        :height="10"
        @change="onVolumeChange" />
    </div>

    <div class="music-order">
      <img alt="随机" title="随机" src="@renderer/assets/img/random.svg" />
    </div>

    <!-- 音乐播放器 -->
    <audio ref="audioPlayer" @loadedmetadata="getDuration" @timeupdate="updateTime" @ended="next"></audio>
    <!-- 音乐列表弹窗 -->
    <BgMusicListDialog ref="bgMusicListDialogRef" @change="onMusicChange" />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import ProgressBar from './ProgressBar.vue';
import BgMusicListDialog from './bgMusicListDialog.vue';

const bgMusicListDialogRef = ref();

const audioPlayer: any = ref(null);
const state: any = reactive({
  musicList: [],
  currentIndex: 0,
  currentSong: {},
  isPlay: false, // 是否播放,默认不播放
  currentTime: 0, // 当前音乐时间
  totalTime: 0, // 总时长
});

// 当前设备音量(最大值100)
const currentVolume = ref(30);

onMounted(async () => {
  await getMusicList();
  if (state.musicList.length) {
    state.currentIndex = 0;
    loadSong();
  }
  console.log('---onMounted-getMusicList');
});

const onListClick = async () => {
  await getMusicList();
  if (state.musicList.length) {
    bgMusicListDialogRef.value.openDialog(state.musicList, state.currentIndex);
  }
};

// 获取音乐列表
const getMusicList = async () => {
  try {
    // 双向通信，返回值是 Promise 实例。
    state.musicList = await window.electron.ipcRenderer.invoke('file:getFileList', '../../resources/mp3');
    console.log('state.musicList: ', state.musicList);
  } catch (error) {
    console.log('error: ', error);
  }
};

// 播放/暂停
const onClickPlay = () => {
  state.isPlay = !state.isPlay;
  if (state.isPlay) {
    play();
  } else {
    pause();
  }
};

// 播放
const play = () => {
  audioPlayer.value?.play();
};

// 暂停
const pause = () => {
  audioPlayer.value?.pause();
};

// 上一首
const prev = () => {
  if (state.currentIndex > 0) {
    state.currentIndex--;
  } else {
    state.currentIndex = state.musicList.length - 1;
  }
  loadSong();
  state.isPlay ? play() : pause();
};

// 下一首
const next = () => {
  if (state.currentIndex < state.musicList.length - 1) {
    state.currentIndex++;
  } else {
    state.currentIndex = 0;
  }
  loadSong();
  state.isPlay ? play() : pause();
};

// 加载歌曲
const loadSong = () => {
  state.currentSong = state.musicList[state.currentIndex]; // 当前播放的歌曲
  console.log('---当前加载歌曲: ', state.currentSong);
  audioPlayer.value.src = state.currentSong.path;
};

// 获取歌曲总时长
const getDuration = () => {
  state.totalTime = +audioPlayer.value.duration;
};

// 时间更新
const updateTime = () => {
  state.currentTime = +audioPlayer.value.currentTime;
};

// 当手动调整音乐后
const onMusicProgressChange = () => {
  audioPlayer.value.currentTime = state.currentTime;
};

// 音量调整
const onVolumeChange = () => {
  audioPlayer.value.volume = (currentVolume.value / 100).toFixed(2);
  console.log('audioPlayer.value.volume: ', audioPlayer.value.volume);
};

// 切换音乐
const onMusicChange = (row: any) => {
  state.currentIndex = row.index - 1;
  loadSong();
  state.isPlay ? play() : pause();
};
</script>

<style lang="scss" scoped>
.bg-music {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  background-color: #1d202b;
  width: 1200px;
  height: 120px;
  padding: 10px 20px;

  .music-player {
    flex: 1;
    display: flex;

    .list {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      width: 100px;
      height: 100px;
      font-size: 14px;
      text-align: center;
      border: 1px solid #ffffff4a;
      margin-right: 20px;

      img {
        width: 60px;
        height: 60px;
      }
    }

    .bar {
      flex: 1;
      padding: 10px;
      display: flex;
      flex-direction: column;
      justify-content: center;

      .title-box {
        display: flex;
        margin-bottom: 10px;

        .music-name {
          font-size: 20px;
          text-align: left;
          margin-right: 20px;
        }

        .music-time {
          width: 200px;
          text-align: center;
          font-size: 16px;
          line-height: 32px;
        }
      }
    }
  }

  .music-operate {
    margin: 0 20px;
    padding: 10px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    width: 200px;
    height: 100%;

    .previous,
    .next {
      cursor: pointer;
      height: 40px;
      text-align: center;
      line-height: 40px;

      img {
        width: 36px;
        height: 36px;
      }
    }

    .play {
      cursor: pointer;
      text-align: center;
      margin: 0 15px;
    }
  }

  .voice-controller {
    padding: 10px;
    display: flex;
    flex-direction: row;
    align-items: center;
    width: 250px;
    height: 100%;
  }

  .music-order {
    padding: 10px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 100%;
  }
}
</style>
